﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using Rabbit.BusinessLogicLayer;
using Rabbit.Modal;
using Rabbit.Utils;

namespace MicroBlogClient
{
    /// <summary>
    /// Interaction logic for FriendsStatus.xaml
    /// </summary>
    public partial class FriendsStatus : PageBase
    {
        #region Observable Collections
        ObservableCollection<Status> FriendsStatusCollection = new ObservableCollection<Status>();
        ObservableCollection<Status> PublicStatusCollection = new ObservableCollection<Status>();
        #endregion

        List<Status> FriendsStatusPool = new List<Status>();
         
        FriendStatusBL friendsStatusBL;
        PublicStatusBL publicStatusBL;

        public FriendsStatus()
        {
            InitializeComponent();
            lstFriendsStatusList.ItemsSource = FriendsStatusCollection;
            lstPublicStatusList.ItemsSource = PublicStatusCollection;

            friendsStatusBL = new FriendStatusBL(MySettings.UpdateInterval.Value);
            publicStatusBL = new PublicStatusBL(MySettings.UpdateInterval.Value);

            //this is used to update the status list
            friendsStatusBL.MainMessageList = FriendsStatusCollection;

            friendsStatusBL.OnPublishAPICallTooFrequent = base.OnCallAPITooFrequentExceptionOccured;
            publicStatusBL.OnPublishAPICallTooFrequent = base.OnCallAPITooFrequentExceptionOccured;

            friendsStatusBL.OnUnknownExceptionOccured = base.OnUnHandledExceptionOccured;
            publicStatusBL.OnUnknownExceptionOccured = base.OnUnHandledExceptionOccured;

            friendsStatusBL.OnMessageInitialized = OnFriendsStatusInitialized;
            friendsStatusBL.OnNewMessageReceived = NewFriendsStatusReceived;

            publicStatusBL.OnMessageInitialized = OnPublicStatusInitialized;
            publicStatusBL.OnNewMessageReceived = NewPublicStatusReceived;

            ShowProcessingMessage("正在加载...");
            BeginInitializeMessage();
        }

        
        private void OnFriendsStatusInitialized(List<Status> messageList)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                messageList.ForEach(s => FriendsStatusCollection.Add(s));
            }), System.Windows.Threading.DispatcherPriority.Background);
             
            base.ShowSuccessfulMessage("加载完成");
        }

        private void OnPublicStatusInitialized(List<Status> messageList)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                messageList.ForEach(s => PublicStatusCollection.Add(s));
            }), System.Windows.Threading.DispatcherPriority.Background);
            base.ShowSuccessfulMessage("加载完成");
        }

        void NewFriendsStatusReceived(List<Status> messageList)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                //refresh the create at showed on the list
                FriendsStatusCollection.ForEach(s => s.CreatedAt = s.CreatedAt); 

                //remove the status that has already existed in current friends status collection
                //or statuses that was forwarded from me
                messageList.RemoveAll(status =>
                    FriendsStatusCollection.Find(t => t.Id == status.Id) != -1 
                    || status.InReplyToUserId == UserBL.CurrentUser.Id);

                if (messageList.Count == 0)
                {
                    return;
                }
                FriendsStatusPool.InsertRange(0, messageList);
               
                TryPopupMessage<Status>(MySettings.PopupForNewStatus,
                    new Action<object, MouseButtonEventArgs>((o, args) =>
                    {
                        this.Dispatcher.BeginInvoke((Action)delegate()
                        {
                            (App.Current.MainWindow as MainWindow).FlushFriendsStatusPool(o, args);
                        });
                    }),
                    FriendsStatusPool.Count,
                    "新微博",
                    messageList[0]);
            }), System.Windows.Threading.DispatcherPriority.Background);
        }

        void NewPublicStatusReceived(List<Status> messageList)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                messageList.RemoveAll(status => PublicStatusCollection.Find(s=>s.Id == status.Id) != -1);
                messageList.ForEach(s =>{
                    PublicStatusCollection.Insert(0, s);
                    if (PublicStatusCollection.Count > MaxRecordsCountShowed)
                    {
                        PublicStatusCollection.RemoveAt(PublicStatusCollection.Count - 1);
                    }
                }); 
            }), System.Windows.Threading.DispatcherPriority.Background);
        }
    
        public override void DoWork(object obj = null)
        {
            if (obj==null)
            {
                App.StopTwinkleSysTrayIcon();
                tabStatusesContent.SelectedItem = tabItemFriendsStatus;

                FriendsStatusCollection.InsertRange(FriendsStatusPool, MaxRecordsCountShowed);
                lstFriendsStatusList.ScrollIntoView(FriendsStatusCollection[0]);
                FriendsStatusPool.Clear();
                NotifyMainWindowNewMessageCountChanged(0);
            }
            else if(obj.GetType() == typeof(Status))
            {
                FriendsStatusCollection.Insert(0,obj as Status);
            }
        }

        protected override void NotifyMainWindowNewMessageCountChanged(int messageCount)
        {
            (App.Current.MainWindow as MainWindow).NewFriendsStatusCount = messageCount;
        }

        #region GetMore Friends Status
        private void btnGetMoreStatus_Click(object sender, RoutedEventArgs e)
        {
            //disable the button first, and then fetch status in a new thread
            btnGetMoreStatus.SetValue(Button.IsEnabledProperty, false);

            //bool IsGetFriendsStatuses = tabStatusesContent.SelectedIndex == 0;
            Action statusFetcher = new Action(() =>
            {
                try
                {
                    List<Status> tempStatuses;
                    tempStatuses = friendsStatusBL.GetMoreFriendsStatus();
                    this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        int count = FriendsStatusCollection.Count;
                        tempStatuses.ForEach(s => FriendsStatusCollection.Add(s));
                    }));
                }
                catch (MaxRatesExceededException ex)
                {
                    ShowFailedMessage(ex);
                }
                catch (Exception ex)
                {
                    LogHelper.LogError(ex);
                    ShowFailedMessage("获取失败，请重试");
                }
                finally
                {
                    this.Dispatcher.BeginInvoke(
                   new Action(() =>
                   {
                       btnGetMoreStatus.SetValue(Button.IsEnabledProperty, true);
                   }
                 ));
                }
            });
            statusFetcher.BeginInvoke(null, null);
        }
        #endregion

        private void tabStatusesContent_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (tabStatusesContent.SelectedIndex == 1 && PublicStatusCollection.Count == 0)
            {
                base.ShowProcessingMessage("正在加载...");
                publicStatusBL.StartFetchingMessage();
            }
        }

        public override void BeginInitializeMessage()
        {
            friendsStatusBL.StartFetchingMessage();
        }
    }
}
